/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.Collections;

namespace ELE.EnterpriseLibrary.Naming.Spi
{
	/// <summary>
  /// This interface represents a factory for creating an object. 
  /// <br/>The ONDI framework allows for object implementations to be loaded in dynamically via object factories. 
  /// For example, when looking up a printer bound in the name space, if the print service binds printer names to 
  /// References, the printer Reference could be used to create a printer object, so that the caller of lookup can 
  /// directly operate on the printer object after the lookup. 
  /// <br/>An IObjectFactory is responsible for creating objects of a specific type. In the above example, you may 
  /// have a PrinterObjectFactory for creating Printer objects. 
  /// <br/>An object factory must implement the IObjectFactory interface. In addition, the factory class must be 
  /// public and must have a public constructor that accepts no parameters. 
  /// <br/>The getObjectInstance() method of an object factory may be invoked multiple times, possibly using 
  /// different parameters. The implementation is thread-safe. 
	/// </summary>
	public interface IObjectFactory
	{
    /// <summary>
    /// Creates an object using the location or reference information specified. 
    /// <br/>Special requirements of this object are supplied using environment. An example of such an environment 
    /// property is user identity information. 
    /// <br/><br/>NamingManager.GetObjectInstance() successively loads in object factories and invokes this method 
    /// on them until one produces a non-null answer. When an exception is thrown by an object factory, the exception 
    /// is passed on to the caller of NamingManager.GetObjectInstance() (and no search is made for other factories 
    /// that may produce a non-null answer). An object factory should only throw an exception if it is sure that it 
    /// is the only intended factory and that no other object factories should be tried. If this factory cannot 
    /// create an object using the arguments supplied, it should return null. 
    /// <br/><br/><b>Name and Context Parameters.</b>
    /// <br/><br/>The name and nameCtx parameters may optionally be used to specify the name of the object being created. 
    /// name is the name of the object, relative to context nameCtx. If there are several possible contexts from 
    /// which the object could be named -- as will often be the case -- it is up to the caller to select one. 
    /// A good rule of thumb is to select the "deepest" context available. If nameCtx is null, name is relative to 
    /// the default initial context. If no name is being specified, the name parameter should be null. If a factory 
    /// uses nameCtx it should synchronize its use against concurrent access, since context implementations are not 
    /// guaranteed to be thread-safe. 
    /// </summary>
    /// <param name="obj">The possibly null object containing location or reference information that can be used in 
    /// creating an object</param>
    /// <param name="name">The name of this object relative to nameCtx, or null if no name is specified</param>
    /// <param name="nameCtx">The context relative to which the name parameter is specified, or null if name is 
    /// relative to the default initial context</param>
    /// <param name="environment">The possibly null environment that is used in creating the object</param>
    /// <returns>The object created; null if an object cannot be created</returns>
    object GetObjectInstance(object obj, IName name, INamingContext nameCtx, Hashtable environment);
	}
}
